package ar.com.photo_admin.service

import java.util.Set
import java.util.logging.Logger

import ar.com.photo_admin.domain.*
import grails.converters.*

/**
 * Service for domain class EventAlbum
 */
class EventAlbumService extends BaseService {

	def eventPhotoService
	
	/**
	 * Gets an EventAlbum using an id if the logged in user is owner of the album.
	 */
	def getAndCheckOwnership(id) {
		User user = springSecurityService.currentUser
		
		def album = EventAlbum.get(id)

		user.isOwner(album) ? album : null
	}
	
	/**
	 * Gets event albums considering logged user permissions.
	 */
	def getAlbumsByEvent(Event event, params = [sort: 'name']) {
		User user = springSecurityService.currentUser
		
		if (user.hasAdminRole())
			EventAlbum.findAllByEvent(event, params)
		else
			EventAlbum.executeQuery("select a from EventAlbum as a where a.event=:event and a.event.deleted=false and (a.event.photographer=:user or a.event.client=:user or a.id in (select uaa.album.id from UserAlbumAccess as uaa where uaa.user=:user))",
				['user': user, 'event': event], params)
	}
	
	/**
	 * Gets all albums considering logged user permissions.
	 */
	def getAlbums(params = [sort: 'name']) {
		User user = springSecurityService.currentUser
		if(user == null)
			return [];
		
		if (user.hasAdminRole())
			EventAlbum.list(params)
		else
			EventAlbum.executeQuery("select a from EventAlbum as a where a.event.deleted=false and (a.event.photographer=:user or a.event.client=:user or a.id in (select uaa.album.id from UserAlbumAccess as uaa where uaa.user=:user))",
				['user': user], params)
	}
	
	/**
	 * Deletes an event album. The event's owner or client are the only users that are allowed to do this operation. 
	 */
	def deleteAlbum(EventAlbum album) {
		def event = album.event
		event.removeFromAlbums(album)

		// Removes all tokens associated with the album
		def tokens = EventAlbumToken.findAll("from EventAlbumToken where ? in elements(albums)", [album])
		tokens.each { token ->			
			token.removeFromAlbums(album)
		}
		
		// Removes all user album accesses
		album.userAlbumAccesses.clear()

		album = album.refresh()
		album.coverPhoto = null		
				
		album.delete()		
	}
	
	/**
	 * Return the photos that are not included in the album but can be because they are associated with the event.
	 */
	def getNotInAlbumButPossiblePhotos(EventAlbum album) {
		
		def eventPhotos = EventPhoto.findAllByEventAndDeleted(album.event, false)
						
		def notInAlbumPhotos = []
			
		def albumPhotos = album.getAlbumPhotos()
						
		eventPhotos.each {
			if(!albumPhotos.contains(it)){
				notInAlbumPhotos.add(it)				
			}
		}
			
		return notInAlbumPhotos
	}
	
	/**
	 * Gets the album photos in JSON format.
	 */
	def getAlbumPhotosAsJSON(EventAlbum album) {
		return eventPhotoService.convertPhotosToJSON(album.getAlbumPhotos())
	}
	
	/**
	 * Gets event photos in JSON format.
	 * @see getNotInAlbumButPossiblePhotos
	 */
	def getNotInAlbumButPossiblePhotosAsJSON(EventAlbum album) {
		def photos = getNotInAlbumButPossiblePhotos(album)
		return eventPhotoService.convertPhotosToJSON(photos)
	}

	/**
	 * Saves or Adds the album to the event 
	 */
	def saveAlbum(EventAlbum album, def coverPhotoId, def selectedPhotosIds, Event event) {
		
		if (album.coverPhoto?.id != coverPhotoId) {
			EventPhoto photo = coverPhotoId != "0" ? eventPhotoService.getAndCheckOwnership(coverPhotoId) : null
			album.coverPhoto = photo
		}
		
		// New album
		if (!album.event)
			event.addToAlbums(album)
			
		album.removeAllPhotos()
			
		def newAlbumPhotos = selectedPhotosIds != [] ? eventPhotoService.getAllAndCheckOwnership(selectedPhotosIds) : []
		
		newAlbumPhotos.each {
			album.addToAlbumPhotos(it)
		}
		
		event.save(flush: true)
	}
	
	/**
	 * Returns the albums that are associated with the token that belong to events that have not been deleted.
	 */
	def getAlbumsByToken(tokenCode) {
		EventAlbumToken token = EventAlbumToken.findByToken(tokenCode)		
		token?.albums.findAll { !it.event.deleted }
	}
	
	/**
	 * Determines whether there is an album with the specified id.
	 */
	def albumExists(id) {
		return EventAlbum.get(id) != null	
	}
}
